package org.common4j2ee.s2shs.service.security;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.common4j2ee.s2shs.dao.user.AuthorityDaoImpl;
import org.common4j2ee.s2shs.entity.user.Authority;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.security.web.util.AntUrlPathMatcher;
import org.springframework.security.web.util.UrlMatcher;


public class UserInvocationSecurityMetadataSourceService implements
		FilterInvocationSecurityMetadataSource {

	private AuthorityDaoImpl authDao;
	

	private UrlMatcher urlMatcher = new AntUrlPathMatcher();
	private static Map<String, Collection<ConfigAttribute>> resourceMap = null;

	public UserInvocationSecurityMetadataSourceService() {
		loadResourceDefine();
	}

	
	private void loadResourceDefine() {
		
		ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
		SessionFactory sessionFactory = (SessionFactory)context.getBean("sessionFactory");
		
		Session session = sessionFactory.openSession();

		List<Authority> authList=(List<Authority>)(session.createQuery("from Authority")).list();
		
		resourceMap = new HashMap<String, Collection<ConfigAttribute>>();
	
		for (Authority auth : authList) {
			
			String authName=auth.getName();
			ConfigAttribute ca = new SecurityConfig(authName);// "ROLE_ADMIN"
			
			List<String> query1=session.createSQLQuery("select r.resources " +
					"from T_AUTHORITY_RESOURCES tar,T_RESOURCES r,  T_AUTHORITY a " +
					"where tar.RESOURCES_ID=r.id and " +
					" tar.AUTHORITY_ID=a.id  and " +
					"   a.name='"+authName+"'").list();
			
			for (String res : query1) {
				String url = res;
				// 判断资源文件和权限的对应关系，如果已经存在，要进行增加
				if (resourceMap.containsKey(url)) {
					Collection<ConfigAttribute> value = resourceMap.get(url);
					value.add(ca);
					resourceMap.put(url, value);
					// "log.jsp","role_user,role_admin"
				} else {
					Collection<ConfigAttribute> atts = new ArrayList<ConfigAttribute>();
					atts.add(ca);
					resourceMap.put(url, atts);
				}
			}
		}
	}

	public Collection<ConfigAttribute> getAttributes(Object object)
			throws IllegalArgumentException {
		String url = ((FilterInvocation) object).getRequestUrl();
		if(resourceMap==null){
			return null;
		}
		Iterator<String> ite = resourceMap.keySet().iterator();
		while (ite.hasNext()) {
			String resURL = ite.next();
			if (urlMatcher.pathMatchesUrl(url, resURL)) {
				return resourceMap.get(resURL);
			}
		}
		return null;
	}

	public boolean supports(Class<?> clazz) {
		return true;
	}

	public Collection<ConfigAttribute> getAllConfigAttributes() {
		return null;
	}


	public AuthorityDaoImpl getAuthDao() {
		return authDao;
	}


	public void setAuthDao(AuthorityDaoImpl authDao) {
		this.authDao = authDao;
	}


	public UrlMatcher getUrlMatcher() {
		return urlMatcher;
	}


	public void setUrlMatcher(UrlMatcher urlMatcher) {
		this.urlMatcher = urlMatcher;
	}

}

